main_activity
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是被查到的資料hihi"
android:textSize="34sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.383" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="388dp"
android:text="查詢"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.rxjava_retorfit_2;
import java.util.List;
import io.reactivex.rxjava3.core.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface jsonplaceholder {
//拿取後段的網址 以'?'為界線
//Observable<放入創立的class抓取資料>
//notice: jsonplaceholder開頭資料是由list包起來的
@GET("posts")
Observable<List<jsonplaceholderdata>> getdata(
);
}
package com.example.rxjava_retorfit_2;
public class jsonplaceholderdata {
private int id;
public int getId() {
return id;
}
}
MianActivity
package com.example.rxjava_retorfit_2;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
//設定URL
private final String BASE_URL = "https://jsonplaceholder.typicode.com/";
//宣告變數
TextView data_Textview;
Button query_button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//綁定元件
ById();
//查詢按鈕
Query_button();
}
//查詢按鈕
private void Query_button(){
query_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//拿取jsonplaceholder 的資料與service連線
getjsondata();
}
});
}
//拿取jsonplaceholder 的資料
private void getjsondata(){
ProgressDialog dialog_wait = new ProgressDialog(MainActivity.this); //網路延遲的對話框
ProgressDialog dialog = new ProgressDialog(MainActivity.this); //進度跑調的對話框
//建立retorfit連線
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.baseUrl(BASE_URL) //設定基本URL
.build();
jsonplaceholder myjson_service = retrofit.create(jsonplaceholder.class);
//notice 資料夾 app\manifests\AndroidManifest.xml
//開頭需要放入網路權限<uses-permission android:name="android.permission.INTERNET" />
//拿取service資料
//解說函式 subscribeOn() : 我被觀察者(Observerable)被指定的路線是主程緒或副程序
//解說函式 observeOn() : 我的觀察者也就是我的UI介面,顯示在主線程或副線程上
//解說函式 subscribe() : 代表我訂閱的觀察者(也就是我的UI介面),且畫面會顯示在我指定的觀察者身上
// AndroidSchedulers.mainThread() 主線程路線
// Schedulers.io() 副線程路線
myjson_service.getdata()
.delay(2, TimeUnit.SECONDS) // 模擬網路延遲
.subscribeOn(Schedulers.io()) //Schedulers.io() 如果有網路、檔案存取需求推薦使用,Rxjava 會幫我們管理 ThreadPool reuse 的部分。
.observeOn(Schedulers.io()) // observeOn是指主畫面顯示 在()裡是 指在副線程執行回覆。
.subscribe(new Observer<List<jsonplaceholderdata>>() { //訂閱
//初始化
@Override
public void onSubscribe(@NonNull Disposable d) {
Toast.makeText(MainActivity.this,"開始", Toast.LENGTH_SHORT).show();
dialog_wait.setTitle("進度");
dialog_wait.setMessage("等待中...");
dialog_wait.show(); //顯示網路延遲的對話框
SetMyProgress(dialog); //設定進度挑
}
//連線成功做動作
@Override
public void onNext(@NonNull List<jsonplaceholderdata> jsonplaceholderdata) {
Log.d("Title","請求成功");
dialog_wait.dismiss(); //關閉網路延遲對話框
runOnUiThread(()->{
dialog.show(); //顯示進度跑調的對話框
});
for(int i = 0; i < 10; i++){
int count = i;
int progressValue = (count + 1) * 10;
runOnUiThread(() -> {
//notice dialog.setProgress(progressValue); // 設定進度條的值 要放在runOnUiThread(()裡
//否則會發生更新數值沒有在UI畫面上
dialog.setProgress(progressValue); // 設定進度條的值
data_Textview.setText(Integer.toString(jsonplaceholderdata.get(count).getId()));
});
//當到達100就關閉進度挑
if(progressValue >= 100){
dialog.dismiss(); //關閉對話框
}
mydelay(); //自訂延遲打包程式碼看起來比較精簡
}
}
//連線失敗做動作
@Override
public void onError(@NonNull Throwable e) {
Log.d("Title","請求失敗");
}
//完成所有執行做動作
@Override
public void onComplete() {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this,"完成", Toast.LENGTH_SHORT).show();
});
}
});
}
//進度挑設定
private void SetMyProgress(ProgressDialog dialog){
dialog.setMessage("載入中...");
dialog.setCancelable(false);//關閉
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//設置進度條樣式 - 水平
dialog.setMax(100); // 設定進度條最大值
}
//綁定元件
private void ById(){
data_Textview = findViewById(R.id.textView);
query_button = findViewById(R.id.button);
}
//用內建有的函數做延遲
//notice 要做try AND catch 否則會報錯
private void mydelay(){
try{
Thread.sleep(1000);
}
catch (Exception e){
System.out.println("Error" + e);
}
}
}
1.建立網路的部分
//建立retorfit連線
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.baseUrl(BASE_URL) //設定基本URL
.build();
jsonplaceholder myjson_service = retrofit.create(jsonplaceholder.class);
Retrofit 是一個用於簡化和處理 HTTP 請求的庫,通常用於從網路服務中檢索數據。
myjson_service.getdata()
.delay(2, TimeUnit.SECONDS) // 模擬網路延遲
.subscribeOn(Schedulers.io()) //Schedulers.io() 如果有網路、檔案存取需求推薦使用,Rxjava 會幫我們管理 ThreadPool reuse 的部分。
.observeOn(Schedulers.io()) // observeOn是指主畫面顯示 在()裡是 指在副線程執行回覆。
.subscribe(new Observer<List<jsonplaceholderdata>>() { //訂閱
//初始化
@Override
public void onSubscribe(@NonNull Disposable d) {
}
//連線成功做動作
@Override
public void onNext(@NonNull List<jsonplaceholderdata> jsonplaceholderdata) {
}
//連線失敗做動作
@Override
public void onError(@NonNull Throwable e) {
}
//完成所有執行做動作
@Override
public void onComplete() {
}
});
-----總結-----
1.subscribeOn() :代表我訂閱的被觀察者是指定走主線程或副線程
2.observeOn() :代表我觀察者也就是我的主畫面UI指定的路線是主線程或副線程
3.subscribe() :這個函式代表我訂閱的觀察者(UI),會顯示畫面在我所指定的觀察者身上
4.各個函式內的線程的部分
Schedulers.io() : 副線程
AndroidSchedulers.mainThread() : 主線程